package com.atguigu.tingshu.search.service.impl;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.aggregations.Aggregate;
import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.album.client.CategoryFeignClient;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.util.PinYinUtils;
import com.atguigu.tingshu.model.album.*;
import com.atguigu.tingshu.model.search.AlbumInfoIndex;
import com.atguigu.tingshu.model.search.AttributeValueIndex;
import com.atguigu.tingshu.model.search.SuggestIndex;
import com.atguigu.tingshu.query.search.AlbumIndexQuery;
import com.atguigu.tingshu.search.repository.AlbumIndexRepository;
import com.atguigu.tingshu.search.repository.SuggestIndexRepository;
import com.atguigu.tingshu.search.service.SearchService;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.atguigu.tingshu.vo.search.AlbumInfoIndexVo;
import com.atguigu.tingshu.vo.search.AlbumSearchResponseVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration;
import org.springframework.data.elasticsearch.core.suggest.Completion;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import co.elastic.clients.elasticsearch.core.search.Suggestion;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Function;
import java.util.stream.Collectors;


@Slf4j
@Service
@SuppressWarnings({"all"})
public class SearchServiceImpl implements SearchService {

    private final AutoServiceRegistrationAutoConfiguration autoServiceRegistrationAutoConfiguration;

    public SearchServiceImpl(AutoServiceRegistrationAutoConfiguration autoServiceRegistrationAutoConfiguration) {
        this.autoServiceRegistrationAutoConfiguration = autoServiceRegistrationAutoConfiguration;
    }

    @Autowired
    private AlbumInfoFeignClient albumInfoFeignClient;

    @Autowired
    private CategoryFeignClient categoryFeignClient;

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    @Autowired
    private AlbumIndexRepository albumIndexRepository;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @Autowired
    private SuggestIndexRepository suggestIndexRepository;

    @Autowired
    private ElasticsearchClient elasticsearchClient;


    @Value("${ranking.dimension.array}")
    private String rankingDimensionArray;

    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public List<AlbumInfoIndex> findRankingList(Long category1Id, String rangking) {

        return (List<AlbumInfoIndex>) redisTemplate.opsForHash().get(RedisConstant.RANKING_KEY_PREFIX+category1Id, rangking);
    }

    @Override
    public void updateLatelyAlbumRanking() {
        //  先获取到所有一级分类数据
        Result<List<BaseCategory1>> baseCategory1Result = categoryFeignClient.findAllCategory1();
        Assert.notNull(baseCategory1Result, "查询一级分类集合失败");
        List<BaseCategory1> baseCategory1List = baseCategory1Result.getData();
        Assert.notNull(baseCategory1List, "查询一级分类集合失败");
        //  获取排序的维度；
        String[] split = rankingDimensionArray.split(",");
        //循环遍历集合 调用es生dsl语句执行并获取结果放入缓存
        for (BaseCategory1 baseCategory1 : baseCategory1List) {
            //  获取一级分类Id
            Long category1Id = baseCategory1.getId();
            for (String rangking : split) {
                //  调用es api
                SearchResponse<AlbumInfoIndex> searchResponse = null;
                try {
                    searchResponse = elasticsearchClient.search(
                            s -> s.index("albuminfo")
                                    .query(q -> q.term(t -> t.field("category1Id").value(category1Id)))
                                    .sort(s1 -> s1.field(f -> f.field(rangking).order(SortOrder.Desc)))
                            ,
                            AlbumInfoIndex.class);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                //  获取集合列表;
                List<AlbumInfoIndex> albumInfoIndexList = searchResponse.hits().hits().stream().map(Hit::source).collect(Collectors.toList());
                //  将每次获取的数据添加到缓存中;
                redisTemplate.opsForHash().put(RedisConstant.RANKING_KEY_PREFIX + category1Id, rangking, albumInfoIndexList);
            }
        }

    }

    @Override
    public List<Map<String, Object>> channel(Long category1Id) {
        //  根据一级分类Id 查询置顶频道页的三级分类列表。7条三级分类的数据
        Result<List<BaseCategory3>> baseCategory3ListResult = categoryFeignClient.findTopBaseCategory3(category1Id);
        Assert.notNull(baseCategory3ListResult, "查询三级分类集合失败");
        List<BaseCategory3> baseCategory3List = baseCategory3ListResult.getData();
        Assert.notNull(baseCategory3List, "查询三级分类集合失败");
        // 获取三级分类id
        List<Long> category3IdList = baseCategory3List.stream().map(BaseCategory3::getId).collect(Collectors.toList());

        //通过三级分类id查找三级分类对象。
        Map<Long, BaseCategory3> category3Map = baseCategory3List.stream().collect(Collectors.toMap(BaseCategory3::getId, Function.identity()));

        List<FieldValue> fieldValueList = baseCategory3List.stream().map(baseCategory3 -> FieldValue.of(baseCategory3.getId())).collect(Collectors.toList());
        // dsl语句。先查询所有三级分类下列表，再分类

        SearchResponse<AlbumInfoIndex> searchResponse = null;
        try {
            searchResponse = elasticsearchClient.search(s -> s.index("albuminfo").query(q -> q.terms(t -> t.field("category3Id")
                                    .terms(t1 -> t1.value(fieldValueList))))
                            .aggregations("agg_category3Id", a -> a.terms(t -> t.field("category3Id"))
                                    .aggregations("topSixHotScoreAgg", a1 -> a1.topHits(t1 -> t1.size(6)
                                            .sort(s1 -> s1.field(f -> f.field("hotScore").order(SortOrder.Desc)))))
                            )
                    , AlbumInfoIndex.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // 封装返回结果

        Aggregate aggregate = searchResponse.aggregations().get("agg_category3Id");
        List<Map<String, Object>> list = aggregate.lterms().buckets().array().stream().map(bucket -> {
            //  存储数据；需要创建一个map集合：
            HashMap<String, Object> map = new HashMap<>();
            //  先获取key;
            long category3Id = bucket.key();
            //  存储第一个数据三级分类对象： baseCategory3.name
            map.put("baseCategory3", category3Map.get(category3Id));
            //  获取专辑集合列表;
            Aggregate topSixHotScoreAgg = bucket.aggregations().get("topSixHotScoreAgg");
            List<AlbumInfoIndex> albumInfoIndexList = topSixHotScoreAgg.topHits().hits().hits().stream()
                    .map(hit -> JSON.parseObject(hit.source().toString(), AlbumInfoIndex.class)).collect(Collectors.toList());
            map.put("list", albumInfoIndexList);
            //  返回map;
            return map;
        }).collect(Collectors.toList());
            return list;
    }

    @Override
    public List<String> completeSuggest(String keyword) {
        //  编写: dsl 语句
        SearchResponse<SuggestIndex> searchResponse = null;
        try {
            searchResponse = elasticsearchClient.search(
                    s -> s.index("suggestinfo")
                            .suggest(s1 -> s1.suggesters("suggest_keyword"
                                                    ,
                                                    f -> f.prefix(keyword).completion(c -> c.field("keyword")
                                                            .skipDuplicates(true)
                                                            .fuzzy(f1 -> f1.fuzziness("auto"))
                                                            .size(10))
                                            )
                                            .suggesters("suggest_keywordPinyin"
                                                    ,
                                                    f -> f.prefix(keyword).completion(c -> c.field("keywordPinyin")
                                                            .skipDuplicates(true)
                                                            .fuzzy(f1 -> f1.fuzziness("auto"))
                                                            .size(10))
                                            )
                                            .suggesters("suggest_keywordSequence"
                                                    ,
                                                    f -> f.prefix(keyword).completion(c -> c.field("keywordSequence")
                                                            .skipDuplicates(true)
                                                            .fuzzy(f1 -> f1.fuzziness("auto"))
                                                            .size(10))
                                            )
                            )
                    ,
                    SuggestIndex.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //  获取到查询结果集：
        List<String> list = new ArrayList<>();
        //  定义一个方法：
        list.addAll(this.getSuggestList(searchResponse, "suggest_keyword"));
        list.addAll(this.getSuggestList(searchResponse, "suggest_keywordPinyin"));
        list.addAll(this.getSuggestList(searchResponse, "suggest_keywordSequence"));
        //  返回数据
        return list;
    }

     //获取题词库数据
    private Collection<String> getSuggestList(SearchResponse<SuggestIndex> searchResponse, String keyword) {
        //  根据key 获取options:
        List<Suggestion<SuggestIndex>> suggestionList = searchResponse.suggest().get(keyword);
        if (!CollectionUtils.isEmpty(suggestionList)) {
            for (Suggestion<SuggestIndex> suggestIndexSuggestion : suggestionList) {
//            List<String> list = suggestIndexSuggestion.completion().options().stream().map(option -> {
//                String title = option.source().getTitle();
//                return title;
//            }).collect(Collectors.toList());
                return suggestIndexSuggestion.completion().options().stream().map(option -> option.source().getTitle()).collect(Collectors.toList());
            }
        }
        //  返回数据
        return new ArrayList<>();
    }


    //前端发送搜索请求，携带搜索条件（关键词、分类、属性、分页、排序等）
    //请求参数封装在 AlbumIndexQuery 对象中
    @Override
    public AlbumSearchResponseVo search(AlbumIndexQuery albumIndexQuery) {
        //服务端构建DSL查询语句
        //  1. 先获取到用户检索的DSL语句;queryBuildDsl 方法根据前端参数构建 Elasticsearch 查询DSL
        SearchRequest searchRequest = this.queryBuildDsl(albumIndexQuery);
        SearchResponse<AlbumInfoIndex> searchResponse = null;
        try {
            // 发送DSL语句给Elasticsearch，使用 ElasticsearchClient 执行构建好的查询请求
            searchResponse = elasticsearchClient.search(searchRequest, AlbumInfoIndex.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //  赋值--private List<AlbumInfoIndexVo> list = new ArrayList<>();
        //parseResultData 方法处理ES返回的原始数据，提取高亮字段，将数据转换为前端需要的VO格式
        AlbumSearchResponseVo albumSearchResponseVo = this.parseResultData(searchResponse);
        //  其他属性赋值；
        albumSearchResponseVo.setTotal(searchResponse.hits().total().value());
        albumSearchResponseVo.setPageNo(albumIndexQuery.getPageNo());
        albumSearchResponseVo.setPageSize(albumIndexQuery.getPageSize());
        //  计算总页数; Long类型取整，弃小数
        //  Long totalPages = albumSearchResponseVo.getTotal()%albumIndexQuery.getPageSize()==0?albumSearchResponseVo.getTotal()/albumIndexQuery.getPageSize():albumSearchResponseVo.getTotal()/albumIndexQuery.getPageSize()+1;
        Long totalPages = (albumSearchResponseVo.getTotal() + albumIndexQuery.getPageSize() - 1) / albumIndexQuery.getPageSize();
        albumSearchResponseVo.setTotalPages(totalPages);
        //  返回数据;
        return albumSearchResponseVo;
    }

    //定义一个私有方法 parseResultData，用于解析 Elasticsearch 搜索响应结果，返回封装后的搜索结果对象 AlbumSearchResponseVo
    private AlbumSearchResponseVo parseResultData(SearchResponse<AlbumInfoIndex> searchResponse) {
        // 创建用于返回给前端的搜索结果对象 AlbumSearchResponseVo 实例
        AlbumSearchResponseVo albumSearchResponseVo = new AlbumSearchResponseVo();
        //创建一个 AlbumInfoIndexVo 对象列表，用于存储处理后的搜索结果
        List<AlbumInfoIndexVo> list = new ArrayList<>();
        // 循环遍历Elasticsearch 搜索响应中的每一个命中的文档（hit）
        for (Hit<AlbumInfoIndex> hit : searchResponse.hits().hits()) {
            //从当前命中的文档中获取原始的 AlbumInfoIndex 对象数据
            AlbumInfoIndex albumInfoIndex = hit.source();
            // 创建一个新的 AlbumInfoIndexVo 对象，用于封装处理后的数据
            AlbumInfoIndexVo albumInfoIndexVo = new AlbumInfoIndexVo();
            // 赋值
            BeanUtils.copyProperties(albumInfoIndex, albumInfoIndexVo);

            //  判断是否有高亮显示：
            if (null != hit.highlight().get("albumTitle")) {
                //  高亮字段;获取 albumTitle 字段的第一个高亮片段（通常是包含搜索关键词并带有高亮标签的文本）
                String albumTitle = hit.highlight().get("albumTitle").get(0);
                //  将高亮字段赋值给对象：替换原始标题
                albumInfoIndexVo.setAlbumTitle(albumTitle);
            }
            //  将对象添加到集合中
            list.add(albumInfoIndexVo);
        }
        //  赋值：
        albumSearchResponseVo.setList(list);
        //  返回数据;
        return albumSearchResponseVo;
    }


    private SearchRequest queryBuildDsl(AlbumIndexQuery albumIndexQuery) {
        // 创建查询对象,因为要用到index，所以现在只Builder()，不需build()
        SearchRequest.Builder searchRequestBuilder = new SearchRequest.Builder();
        // BoolQuery
        BoolQuery.Builder boolQuery = new BoolQuery.Builder();
        //指定索引库
        searchRequestBuilder.index("albuminfo");
        // 根据关键词检索
        if(!StringUtils.isEmpty(albumIndexQuery.getKeyword())){
            boolQuery.should(s->s.match(m->m.field("albumTitle").query(albumIndexQuery.getKeyword())))  // 专辑标题
                    .should(s->s.match(m->m.field("albumIntro").query(albumIndexQuery.getKeyword())))   // 专辑简介
                    .should(s->s.match(m->m.field("announcerName").query(albumIndexQuery.getKeyword())));  // 作者
        //高亮
            searchRequestBuilder.highlight(h->h.fields("albumTitle", f->f.preTags("<span style='color:red'>")
                    .postTags("</span>")));
        }

        // 根据专辑分类检索
        if(!StringUtils.isEmpty(albumIndexQuery.getCategory1Id())){
            // 根据一级分类id过滤
            boolQuery.filter(f->f.term(t->t.field("category1Id").value(albumIndexQuery.getCategory1Id())));
        }
        if(!StringUtils.isEmpty(albumIndexQuery.getCategory2Id())){
            // 根据二级分类id过滤
            boolQuery.filter(f->f.term(t->t.field("category2Id").value(albumIndexQuery.getCategory2Id())));
        }
        if(!StringUtils.isEmpty(albumIndexQuery.getCategory3Id())){
            // 根据三级分类id过滤
            boolQuery.filter(f->f.term(t->t.field("category3Id").value(albumIndexQuery.getCategory3Id())));
        }

        // 根据专辑属性与属性值过滤检索
        List<String> attributeList = albumIndexQuery.getAttributeList();
        if(!CollectionUtils.isEmpty(attributeList)){
            // 循环遍历
            for (String attribute : attributeList) {
                // 属性：属性值
                String[] split = attribute.split(":");
                if(null != split && split.length == 2){
                    boolQuery.filter(f->f.nested(n->n.path("attributeValueIndexList")
                            .query(q->q.bool(b->b.must(m->m.term(t->t.field("attributeValueIndexList.attributeId").value(split[0])))
                                    .must(m->m.term(t->t.field("attributeValueIndexList.valueId").value(split[1])))
                            ))
                    ));
                }
            }
        }
        //分页
        searchRequestBuilder.from((albumIndexQuery.getPageNo()-1)*albumIndexQuery.getPageSize());
        searchRequestBuilder.size(albumIndexQuery.getPageSize());
        //排序
        String order = albumIndexQuery.getOrder();
        if(!StringUtils.isEmpty(order)){
            String[] split = order.split(":");
            if(null != split && split.length == 2){
                String field = "hotScore"; //默认综合排序
               switch (split[0]){
                   case "1":
                       field = "hotScore"; // 综合排序
                       break;
                   case "2":
                       field = "playStatNum"; // 播放量
                       break;
                   case "3":
                       field = "createTime"; // 发布时间
               }
                String finalField1 = field;
                searchRequestBuilder.sort(s->s.field(f->f.field(finalField1).order("asc".equals(split[1])?SortOrder.Asc: SortOrder.Desc)));
            }

        }

        //设置bool--> query中
        searchRequestBuilder.query(boolQuery.build()._toQuery());
        //对象build()
        SearchRequest searchRequest = searchRequestBuilder.build();
        //打印DSL语句
        System.out.println("DSL:\t"+searchRequest.toString());
        return searchRequest;

    }

    @Override
    public void upperAlbum(Long albumId) {
        //使用AlbumInfoIndex，实体类，上架字段属性
        AlbumInfoIndex albumInfoIndex = new AlbumInfoIndex();

        //使用多线程
        CompletableFuture<AlbumInfo> albumInfoCompletableFuture = CompletableFuture.supplyAsync(() -> {
            //赋值 album_info表内的信息。通过 Feign 客户端远程调用专辑服务，获取指定 ID 的专辑信息。
            Result<AlbumInfo> albumInfoResult = albumInfoFeignClient.getAlbumInfo(albumId);
            //使用 Spring 的 Assert 工具类检查 albumInfoResult 是否为 null。
            Assert.notNull(albumInfoResult, "查询专辑信息失败");
            //获取专辑对象-提取实际的专辑信息对象
            AlbumInfo albumInfo = albumInfoResult.getData();
            //判断专辑对象为空
            Assert.notNull(albumInfo, "查询专辑信息失败");
            //赋值 albumInfoIndex
            BeanUtils.copyProperties(albumInfo, albumInfoIndex);

            //---------------------------
            //获取属性与属性值数据
            List<AlbumAttributeValue> albumAttributeValueVoList = albumInfo.getAlbumAttributeValueVoList();
            if(!CollectionUtils.isEmpty(albumAttributeValueVoList)){
               /* //创建集合
                List<AttributeValueIndex> attributeValueIndexList = albumInfoIndex.getAttributeValueIndexList();
                //循环遍历赋值：
                for (AlbumAttributeValue albumAttributeValue : albumAttributeValueVoList) {
                    //创建对象
                   AttributeValueIndex attributeValueIndex = new AttributeValueIndex();
                   //赋值
                   attributeValueIndex.setAttributeId(albumAttributeValue.getAttributeId());
                   attributeValueIndex.setValueId(albumAttributeValue.getValueId());
                   //添加到集合
                   attributeValueIndexList.add(attributeValueIndex);
                }*/
                //循环遍历赋值：
                List<AttributeValueIndex> attributeValueIndexList = albumAttributeValueVoList.stream().map(albumAttributeValue -> {
                    AttributeValueIndex attributeValueIndex = new AttributeValueIndex();
                    attributeValueIndex.setAttributeId(albumAttributeValue.getAttributeId());
                    attributeValueIndex.setValueId(albumAttributeValue.getValueId());
                    return attributeValueIndex;
                }).collect(Collectors.toList());
                //添加到属性与属性值集合
                albumInfoIndex.setAttributeValueIndexList(attributeValueIndexList);
            }
            return albumInfo;
        },threadPoolExecutor).exceptionally(throwable -> {
            log.error("查询专辑信息失败：{}", throwable.getMessage());
            return null;
        });
        //=======================
        //分类。从上面代码的返回值里获取三级分类id，用getCategory3Id查视图
        CompletableFuture<Integer> cateCompletableFuture = albumInfoCompletableFuture.thenApplyAsync(albumInfo -> {
            //  远程调用根据三级分类ID 获取分类数据;
            Result<BaseCategoryView> categoryViewResult = categoryFeignClient.getBaseCategoryView(albumInfo.getCategory3Id());
            //  判断数据;
            Assert.notNull(categoryViewResult, "查询分类数据失败-categoryViewResult");
            BaseCategoryView baseCategoryView = categoryViewResult.getData();
            Assert.notNull(baseCategoryView, "查询分类数据失败");
            //  赋值：
            albumInfoIndex.setCategory1Id(baseCategoryView.getCategory1Id());
            albumInfoIndex.setCategory2Id(baseCategoryView.getCategory2Id());
            return 1;
        }, threadPoolExecutor).exceptionally(throwable -> {
            log.error("查询分类数据失败：{}", throwable.getMessage());
            return 0;
        });

        //=======================
        //查询用户id=>作者信息
        CompletableFuture<Integer> userCompletableFuture = albumInfoCompletableFuture.thenApplyAsync(albumInfo -> {

            Result<UserInfoVo> userInfoResult = userInfoFeignClient.getUserInfoVo(albumInfo.getUserId());
            Assert.notNull(userInfoResult, "查询作者信息失败");
            UserInfoVo userInfoVo = userInfoResult.getData();
            Assert.notNull(userInfoVo, "查询作者信息失败");
            albumInfoIndex.setAnnouncerName(userInfoVo.getNickname());

            return 1;
        },threadPoolExecutor).exceptionally(throwable -> {
            log.error("查询作者信息失败：{}", throwable.getMessage());
            return 0;
        });

        //=======================
        //根据专辑ID 查询专辑统计数据
        //偷懒版，直接随机生成，不从数据库查值
       /* albumInfoIndex.setPlayStatNum(new Random().nextInt(1000));
        albumInfoIndex.setSubscribeStatNum(new Random().nextInt(1000));
        albumInfoIndex.setBuyStatNum(new Random().nextInt(1000));
        albumInfoIndex.setCommentStatNum(new Random().nextInt(1000));*/
        //专辑热度
        albumInfoIndex.setHotScore(Double.valueOf(new Random().nextInt(10000)));

        //根据专辑id从数据库查值
        CompletableFuture<Integer> albumStatCompletableFuture = albumInfoCompletableFuture.thenApplyAsync(albumInfo -> {
            Result<AlbumStatVo> albumStatVo = albumInfoFeignClient.getAlbumStatVo(albumId);
            Assert.notNull(albumStatVo, "查询专辑统计数据失败");
            AlbumStatVo albumStatVo1 = albumStatVo.getData();
            Assert.notNull(albumStatVo1, "查询专辑统计数据失败");
            albumInfoIndex.setPlayStatNum(albumStatVo1.getPlayStatNum());
            albumInfoIndex.setSubscribeStatNum(albumStatVo1.getSubscribeStatNum());
            albumInfoIndex.setBuyStatNum(albumStatVo1.getBuyStatNum());
            albumInfoIndex.setCommentStatNum(albumStatVo1.getCommentStatNum());
            return 1;
            },threadPoolExecutor).exceptionally(throwable -> {
                log.error("查询专辑统计数据失败：{}", throwable.getMessage());
                return 0;
            });


        try {
            if(null == albumInfoCompletableFuture.get() ||  0 == cateCompletableFuture.get() || 0 == userCompletableFuture.get() || 0 == albumStatCompletableFuture.get()){
                //获取专辑信息失败
                throw new GuiguException(20001,"远程调用获取专辑信息失败");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }


        //等待所有任务执行完成,数据汇总
        //CompletableFuture.allOf(albumInfoCompletableFuture,cateCompletableFuture, userCompletableFuture).join();
        // 调用es的api进行数据保存 albumInfoIndex-》es
        albumIndexRepository.save(albumInfoIndex);


        //上架提词库
        SuggestIndex suggestIndex = new SuggestIndex();
        //  赋值：本质赋值的是title;
        suggestIndex.setId(UUID.randomUUID().toString().replace("-", ""));
        suggestIndex.setTitle(albumInfoIndex.getAlbumTitle());
        suggestIndex.setKeyword(new Completion(new String[]{albumInfoIndex.getAlbumTitle()}));
        suggestIndex.setKeywordPinyin(new Completion(new String[]{PinYinUtils.toHanyuPinyin(albumInfoIndex.getAlbumTitle())}));
        suggestIndex.setKeywordSequence(new Completion(new String[]{PinYinUtils.getFirstLetter(albumInfoIndex.getAlbumTitle())}));
        suggestIndexRepository.save(suggestIndex);
        //  介绍;
        SuggestIndex suggestIndexInfo = new SuggestIndex();
        suggestIndexInfo.setId(UUID.randomUUID().toString().replace("-", ""));
        suggestIndexInfo.setTitle(albumInfoIndex.getAlbumIntro());
        suggestIndexInfo.setKeyword(new Completion(new String[]{albumInfoIndex.getAlbumIntro()}));
        suggestIndexInfo.setKeywordPinyin(new Completion(new String[]{PinYinUtils.toHanyuPinyin(albumInfoIndex.getAlbumIntro())}));
        suggestIndexInfo.setKeywordSequence(new Completion(new String[]{PinYinUtils.getFirstLetter(albumInfoIndex.getAlbumIntro())}));
        suggestIndexRepository.save(suggestIndexInfo);
        //  作者;
        SuggestIndex suggestIndexAuthor = new SuggestIndex();
        suggestIndexAuthor.setId(UUID.randomUUID().toString().replace("-", ""));
        suggestIndexAuthor.setTitle(albumInfoIndex.getAnnouncerName());
        suggestIndexAuthor.setKeyword(new Completion(new String[]{albumInfoIndex.getAnnouncerName()}));
        suggestIndexAuthor.setKeywordPinyin(new Completion(new String[]{PinYinUtils.toHanyuPinyin(albumInfoIndex.getAnnouncerName())}));
        suggestIndexAuthor.setKeywordSequence(new Completion(new String[]{PinYinUtils.getFirstLetter(albumInfoIndex.getAnnouncerName())}));
        suggestIndexRepository.save(suggestIndexAuthor);

    }

    @Override
    public void lowerAlbum(Long albumId) {

        // 调用es的api进行数据删除
        albumIndexRepository.deleteById(albumId);
    }
}
